package cn.xyafu.lost.utils;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.widget.ImageView;

import com.nostra13.universalimageloader.cache.disc.naming.Md5FileNameGenerator;
import com.nostra13.universalimageloader.cache.memory.impl.WeakMemoryCache;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.core.assist.ImageScaleType;
import com.nostra13.universalimageloader.core.assist.QueueProcessingType;
import com.nostra13.universalimageloader.core.download.BaseImageDownloader;
import com.nostra13.universalimageloader.core.listener.ImageLoadingListener;

import cn.xyafu.lost.R;

/**
* @author wangdh
* @time 2021/12/9 0009
* desc： 异步图片加载框架的封装工具
*/
public class ImageLoaderManager {

    private static final int THREAD_COUNT = 2 ; //线程数量: 表明我们的UIL 最多可以有多少条线程去加载图片
    private static final int PRIORITY = 2; // 表明图片的优先级, 因为文本加载的优先级比图片高, 所以我们给图片的优先级修改一下
    private static final int DISK_CACHE_SIZE = 50 * 1024 * 1024; // 表明最多本地可以缓存多少图片
    private static final int CONNECTION_TIME_OUT = 5 * 1000; // 连接超时时间
    private static final int READ_TIME_OUT = 30 * 1000;  // 读取超时时间

    private static ImageLoaderManager imageLoaderManager = null;
    private final ImageLoader mLoader;

    //单例的写法: 获取ImageLoaderManager的实例对象
    public static ImageLoaderManager getInstance(Context context){
        if(imageLoaderManager == null){
            synchronized (ImageLoaderManager.class){
                if(imageLoaderManager == null){
                    imageLoaderManager = new ImageLoaderManager(context);
                }
            }
        }
        return imageLoaderManager;
    }

    public ImageLoaderManager(Context context) {
        ImageLoaderConfiguration config = new ImageLoaderConfiguration 
                .Builder(context)  // 实例化config对象
                .threadPoolSize(THREAD_COUNT)   // 线程池的大小: 线程的数量为2
                // 这里并没有直接配置死值PRIORITY:2
                // 因为每个android手机的系统优先级是不一样的, 我们没有办法直接写死图片的优先级
                // 所以需要先获取当前系统的普通的一个优先级级别, 接下来固定减去PRIORITY2, 这样得到的是一个相对的优先级
                // 官网的固定配置
                .threadPriority(Thread.NORM_PRIORITY - PRIORITY) // 设置图片的优先级
                .denyCacheImageMultipleSizesInMemory() //拒绝缓存多种尺寸的图片
                .memoryCache(new WeakMemoryCache())  // 缓存机制采用弱引用: 如果系统内存不足时可以回收图片缓存
                .diskCacheSize(DISK_CACHE_SIZE)  // 本地缓存大小
                .diskCacheFileNameGenerator(new Md5FileNameGenerator())  // 本地缓存图片的名字生成器: md5生成器
                .tasksProcessingOrder(QueueProcessingType.LIFO) // 图片下载顺序: LIFO队列 , 先进先出
                .defaultDisplayImageOptions(getDefaultOptions()) //配置显示图片的选项
                // 图片下载器: 基本的图片下载器(链接超时时间, 读取超时时间)
                .imageDownloader(new BaseImageDownloader(context, CONNECTION_TIME_OUT, READ_TIME_OUT))
                .writeDebugLogs() // 如果是debug模式, 那么就打印log
                .build();
        ImageLoader.getInstance().init(config); // 先配置, 因为init方法返回的是void
        mLoader = ImageLoader.getInstance(); // 再获取实例化对象
    }
    // 显示图片的配置选项
    private DisplayImageOptions getDefaultOptions() {
        DisplayImageOptions options = new
                DisplayImageOptions.Builder() // 实例化显示图片的配置对象
                .showImageForEmptyUri(R.drawable.default_user_avatar) // 如果图片地址为空, 那么设置默认图片
                .showImageOnFail(R.drawable.default_user_avatar)  // 如果图片加载失败, 设置默认图片
                .cacheInMemory(true)  // 开启内存缓存
                .cacheOnDisk(true) // 开启本地硬盘缓存
                .considerExifParams(true)   // 考虑是否有exif参数 , exif: jpeg图片旋转 , 翻转
                .imageScaleType(ImageScaleType.IN_SAMPLE_INT) // 设置图片的缩放模式
                .bitmapConfig(Bitmap.Config.RGB_565)  // 设置图片解码类型, 565 颜色值比较少的一种, 占用空间比较少
                .decodingOptions(new BitmapFactory.Options()) // 解码的配置, 采用的是BitMap的默认配置
                .resetViewBeforeLoading(true)  // 加载之前是否重置图片
                .build();
        return options;
    }
    /**
    * @author wangdh
    * @time 2021/12/9 0009
    * desc：显示图片的方法
     * 1. 图片组件
     * 2. 图片url路径
     * 3. 回调监听
    */
    public void displayImage(ImageView imageView, String path, ImageLoadingListener listener) {
        if (mLoader != null) {
            mLoader.displayImage(path, imageView, listener);
        }
    }
    /**
     * @author wangdh
     * @time 2021/12/9 0009
     * desc：显示图片的方法
     * 1. 图片组件
     * 2. 图片url路径
     */
    public void displayImage(ImageView imageView, String path) {
        displayImage(imageView, path, null);
    }
}
